﻿using Microsoft.EntityFrameworkCore;
using UwinEducation.Domain.Entities;
using UwinEducation.Domain.IRepositories;
using UwinEducation.Infrastructure.Persistence;
using UwinEducation.Shared.Models;

namespace UwinEducation.Infrastructure.Repositories
{
    public class TeacherScheduleDetailsRepository
        : Repository<TeacherScheduleDetails, Guid>,
            ITeacherScheduleDetailsRepository
    {
        public TeacherScheduleDetailsRepository(ApplicationDbContext context)
            : base(context) { }

        public async Task<PagedResult<TeacherScheduleDetails>> GetPagedDetailsListAsync(
            TeacherSchedulePageRequest pageRequest
        )
        {
            // 先构建基础查询并应用过滤条件
            var baseQuery = _context.TeacherScheduleDetails.Where(ts => ts.TeacherSchedule != null);

            // 应用所有过滤条件
            if (pageRequest.TeacherId.HasValue)
            {
                baseQuery = baseQuery.Where(ts =>
                    ts.TeacherSchedule.TeacherId == pageRequest.TeacherId
                );
            }
            if (pageRequest.ClassroomId.HasValue)
            {
                baseQuery = baseQuery.Where(ts =>
                    ts.TeacherSchedule.ClassroomId == pageRequest.ClassroomId
                );
            }
            if (pageRequest.CourseType.HasValue)
            {
                baseQuery = baseQuery.Where(ts => ts.CourseType == pageRequest.CourseType);
            }
            if (pageRequest.GroupId.HasValue)
            {
                baseQuery = baseQuery.Where(ts => ts.TeacherScheduleId == pageRequest.GroupId);
            }
            if (pageRequest.CourseId.HasValue)
            {
                baseQuery = baseQuery.Where(ts =>
                    ts.TeacherSchedule.CourseId == pageRequest.CourseId
                );
            }
            if (pageRequest.StartDate.HasValue)
            {
                baseQuery = baseQuery.Where(ts =>
                    ts.StartTime.Date >= pageRequest.StartDate.Value.Date
                );
            }
            if (pageRequest.EndDate.HasValue)
            {
                baseQuery = baseQuery.Where(ts =>
                    ts.EndTime.Date <= pageRequest.EndDate.Value.Date
                );
            }
            if (!string.IsNullOrEmpty(pageRequest.Remarks))
            {
                baseQuery = baseQuery.Where(ts => ts.Remarks.Contains(pageRequest.Remarks));
            }

            // 先计算总记录数
            var total = await baseQuery.CountAsync();

            // 然后进行投影查询，包含排序和分页,排序先按教师课表ID排序，再按开始时间排序
            var query = baseQuery
                .OrderBy(ts => ts.TeacherSchedule.TeacherId)
                .ThenBy(ts => ts.StartTime)
                .Skip((pageRequest.PageIndex - 1) * pageRequest.PageSize)
                .Take(pageRequest.PageSize)
                .Select(ts => new TeacherScheduleDetails
                {
                    Id = ts.Id,
                    TeacherScheduleId = ts.TeacherScheduleId,
                    StartTime = ts.StartTime,
                    EndTime = ts.EndTime,
                    Status = ts.Status,
                    IsForceCheck = ts.IsForceCheck,
                    Remarks = ts.Remarks,
                    CourseType = ts.CourseType,
                    TeacherSchedule = new TeacherSchedule
                    {
                        Id = ts.TeacherSchedule.Id,
                        TeacherId = ts.TeacherSchedule.TeacherId,
                        CourseId = ts.TeacherSchedule.CourseId,
                        ClassroomId = ts.TeacherSchedule.ClassroomId,
                        UnitPrice = ts.TeacherSchedule.UnitPrice,
                        Capacity = ts.TeacherSchedule.Capacity,
                        StartTime = ts.TeacherSchedule.StartTime,
                        EndTime = ts.TeacherSchedule.EndTime,
                        Status = ts.TeacherSchedule.Status,
                        Reason = ts.TeacherSchedule.Reason,
                        GroupId = ts.TeacherSchedule.GroupId,
                        Course =
                            ts.TeacherSchedule.Course != null
                                ? new Course
                                {
                                    Id = ts.TeacherSchedule.Course.Id,
                                    Name = ts.TeacherSchedule.Course.Name,
                                    Code = ts.TeacherSchedule.Course.Code,
                                    CalendarColor = ts.TeacherSchedule.Course.CalendarColor,
                                    Remarks = ts.TeacherSchedule.Course.Remarks,
                                }
                                : null,
                        Classroom =
                            ts.TeacherSchedule.Classroom != null
                                ? new Classroom
                                {
                                    Id = ts.TeacherSchedule.ClassroomId.Value,
                                    Name = ts.TeacherSchedule.Classroom.Name,
                                    Capacity = ts.TeacherSchedule.Classroom.Capacity,
                                    Remarks = ts.TeacherSchedule.Classroom.Remarks,
                                }
                                : null,
                        Teacher =
                            ts.TeacherSchedule.Teacher != null
                                ? new Teacher
                                {
                                    Id = ts.TeacherSchedule.TeacherId,
                                    Name = ts.TeacherSchedule.Teacher.Name,
                                    Phone = ts.TeacherSchedule.Teacher.Phone,
                                    Email = ts.TeacherSchedule.Teacher.Email,
                                    TeacherNo = ts.TeacherSchedule.Teacher.TeacherNo,
                                    Remarks = ts.TeacherSchedule.Teacher.Remarks,
                                }
                                : null,
                    },
                });

            var items = await query.ToListAsync();

            return new PagedResult<TeacherScheduleDetails> { Total = total, Items = items };
        }

        public override async Task<TeacherScheduleDetails> GetByIdAsync(Guid id)
        {
            var query = _context
                .TeacherScheduleDetails.Include(ts => ts.TeacherSchedule)
                .Include(ts => ts.TeacherSchedule.Classroom)
                .Include(ts => ts.TeacherSchedule.Teacher)
                .Include(ts => ts.TeacherSchedule.Course)
                .AsQueryable();
            return await query.FirstOrDefaultAsync(ts => ts.Id == id);
        }

        public async Task<List<TeacherScheduleDetails>> GetByIdsAsync(List<Guid> ids)
        {
            return await _context
                .TeacherScheduleDetails.Where(ts => ids.Contains(ts.Id))
                .ToListAsync();
        }

        public async Task DeleteRangeAsync(List<TeacherScheduleDetails> scheduleDetails)
        {
            _context.TeacherScheduleDetails.RemoveRange(scheduleDetails);
            await _context.SaveChangesAsync();
        }

        public async Task<List<TeacherScheduleDetails>> GetByTeacherIdAsync(
            Guid teacherId,
            DateTime startTime,
            DateTime endTime
        )
        {
            return await _context
                .TeacherScheduleDetails.Where(ts =>
                    ts.TeacherSchedule.TeacherId == teacherId
                    && ts.StartTime >= startTime
                    && ts.EndTime <= endTime
                )
                .ToListAsync();
        }

        public async Task<List<TeacherScheduleDetails>> GetByTeacherScheduleIdAsync(Guid id)
        {
            return await _context
                .TeacherScheduleDetails.Where(ts => ts.TeacherScheduleId == id)
                .ToListAsync();
        }

        public async Task<PagedResult<TeacherScheduleDetails>> GetPagedStatisticalDetailsListAsync(
            TeacherSchedulePageRequest pageRequest
        )
        {
            var query = _context
                .TeacherScheduleDetails.Include(ts => ts.TeacherSchedule)
                .AsQueryable();
            if (pageRequest.TeacherId.HasValue)
            {
                query = query.Where(ts => ts.TeacherSchedule.TeacherId == pageRequest.TeacherId);
            }
            if (pageRequest.StartDate.HasValue)
            {
                query = query.Where(ts => ts.StartTime.Date >= pageRequest.StartDate.Value.Date);
            }
            if (pageRequest.EndDate.HasValue)
            {
                query = query.Where(ts => ts.EndTime.Date <= pageRequest.EndDate.Value.Date);
            }

            var total = await query.CountAsync();
            var items = await query
                .OrderBy(ts => ts.StartTime)
                .Skip((pageRequest.PageIndex - 1) * pageRequest.PageSize)
                .Take(pageRequest.PageSize)
                .ToListAsync();
            return new PagedResult<TeacherScheduleDetails> { Total = total, Items = items };
        }
    }
}
